package com.taplinker.client.im.domain;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import android.content.Context;
import android.text.TextUtils;

import com.taplinker.client.core.DataManager;
import com.taplinker.client.im.protocol.TapLinkerConversation;
import com.taplinker.client.im.protocol.TapLinkerMessage;
import com.taplinker.client.im.rpc.Cmd003;
import com.taplinker.client.im.rpc.Cmd004;
import com.taplinker.client.im.rpc.Cmd007;
import com.taplinker.client.im.rpc.Cmd010;
import com.taplinker.client.im.rpc.Cmd011;
import com.taplinker.client.im.rpc.Cmd012;
import com.taplinker.client.im.rpc.Cmd013;
import com.taplinker.client.im.rpc.Cmd015;
import com.taplinker.client.im.rpc.Cmd016;
import com.taplinker.client.im.rpc.IMListener;
import com.taplinker.client.im.rpc.body.Cmd013Rep;
import com.taplinker.core.Resource;
import com.taplinker.core.ResourceManager;

public class ImDataCenter extends DataManager implements Resource {
	public static final String TEMPLATE_VERSION = "template_version";
	public static final String TEMPLATE_UPDATE = "template_update";
	public static final String MESSAGE_RECEIVE = "message_receive";
	public static final String MESSAGE_FINISH = "message_finish";
	public static final String REFRESH_FINISH = "refresh_finish";
	public static final String CONVERSATION_NO_MORE = "conversation_no_more";
	public static final String TRANSFER_FINISH = "transfer_finish";
	public static final String CUSTOMER_REFRESH = "customer_refresh";
	public static final String QUEUE_REFRESH = "queue_refresh";
	public static final String MENU_REFRESH = "menu_refresh";
	public static final String HOME_REFRESH="home_refresh";
	public static final String USERLIST_REFRESH = "userlist_refresh";
	public static final String APPOINT_FINISH = "appoint_finish";
	public static final String GET_MATCH_CUSTOMER = "get_match_customer";
	public static final String GET_MATCH_CONVERSATION = "get_match_conversation";
	public static final String SEND_OK = "send_ok";
	public static final String SEND_FAIL = "send_fail";
	public static final String SEND_ERROR = "send_error";
	public static final String UPDATE_USER_INFO = "update_user_info";

	public static final int PAGE_SIZE = 10;
	public static final int MAX_FILE_SIZE = 30; // 30M

	public int crmNum;
	private int priNum;
	private int pubNum;
	private boolean isPublicQueue = true;
	private List<TapLinkerConversation> pubQueue = new LinkedList<TapLinkerConversation>();
	private List<TapLinkerConversation> privQueue = new LinkedList<TapLinkerConversation>();
	
	private TapLinkerConversation conversation = null;

	private static ImDataCenter instance;

	private ImDataCenter() {
	}

	public static ImDataCenter getInstance() {
		if (instance != null) {
			return instance;
		}
		synchronized (ImDataCenter.class) {
			if (instance == null) {
				instance = new ImDataCenter();
				ResourceManager.getInstance().addResource(instance);
			}
		}
		return instance;
	}

	public boolean isPublicQueue() {
		return isPublicQueue;
	}

	public void setPublicQueue(boolean isPublicQueue) {
		this.isPublicQueue = isPublicQueue;
	}

	public TapLinkerConversation getConversation() {
		return conversation;
	}

	public void setConversation(TapLinkerConversation conversation) {
		this.conversation = conversation;
	}

	private List<Cmd013Rep> csList = new ArrayList<Cmd013Rep>();

	public List<TapLinkerConversation> getPubQueue() {
		return pubQueue;
	}

	public List<TapLinkerConversation> getPrivQueue() {
		return privQueue;
	}

	

	public int getPriNum() {
		return priNum;
	}

	public void setPriNum(int priNum) {
		this.priNum = priNum;
		noticeListener(MENU_REFRESH);
		noticeListener(HOME_REFRESH);
	}

	public int getPubNum() {
		return pubNum;
	}

	public void setPubNum(int pubNum) {
		this.pubNum = pubNum;
		noticeListener(MENU_REFRESH);
		noticeListener(HOME_REFRESH);
	}

	public int getCrmNum() {
		return crmNum;
	}

	public void setCrmNum(int crmNum) {
		this.crmNum = crmNum;
		noticeListener(MENU_REFRESH);
		noticeListener(HOME_REFRESH);
	}

	/**
	 * 添加会话列表到公共队列
	 * 
	 * @param list
	 */
	public void addAllPublicQueue(List<TapLinkerConversation> list) {
		pubQueue.addAll(list);
		noticeListener(QUEUE_REFRESH);
	}

	/**
	 * 添加会话列表到我的会话
	 * 
	 * @param list
	 */
	public void addAllPrivateQueue(List<TapLinkerConversation> list) {
		privQueue.addAll(list);
		noticeListener(QUEUE_REFRESH);
	}

	/**
	 * 从公共队列移除会话
	 * 
	 * @param id
	 * @return
	 */
	public TapLinkerConversation removeConversationByIdFromPub(final String id) {
		TapLinkerConversation result = null;
		for (TapLinkerConversation con : pubQueue) {
			if (id.equals(con.getId())) {
				pubQueue.remove(con);
				pubNum--;
				result = con;
				break;
			}
		}
		noticeListener(QUEUE_REFRESH);
		noticeListener(MENU_REFRESH);
		noticeListener(HOME_REFRESH);
		return result;
	}

	/**
	 * 从我的会话移除会话
	 * 
	 * @param id
	 * @return
	 */
	public TapLinkerConversation removeConversationByIdFromPri(final String id) {
		TapLinkerConversation result = null;
		for (TapLinkerConversation con : privQueue) {
			if (id.equals(con.getId())) {
				privQueue.remove(con);
				if (con.getUnreadMessages() > 0) {
					priNum--;
				}
				result = con;
				break;
			}
		}
		noticeListener(QUEUE_REFRESH);
		noticeListener(MENU_REFRESH);
		noticeListener(HOME_REFRESH);
		return result;
	}

	/**
	 * 会话添加消息到我的会话
	 * 
	 * @param con
	 */
	public void addToPublicQueue(final TapLinkerConversation con) {
		pubQueue.add(0, con);
		pubNum++;
		noticeListener(QUEUE_REFRESH);
		noticeListener(MENU_REFRESH);
		noticeListener(HOME_REFRESH);
	}

	/**
	 * 会话添加消息到公共队列
	 * 
	 * @param con
	 */
	public void addToPrivateQueue(final TapLinkerConversation con) {
		con.setQueueType(TapLinkerConversation.PRIVATE_QUEUE);
		privQueue.add(0, con);
		if (con.getUnreadMessages() > 0) {
			priNum++;
		}
		noticeListener(QUEUE_REFRESH);
		noticeListener(MENU_REFRESH);
		noticeListener(HOME_REFRESH);
	}

	/**
	 * 消息添加消息到我的会话
	 * 
	 * @param message
	 */
	public void addToPubMessage(final TapLinkerMessage message) {
		TapLinkerConversation con = getConversation(
				message.getConversationId(), pubQueue);
		if (con != null) {
			if (!TextUtils.isEmpty(con.getCustomerName())) {
				message.setSendUser(con.getCustomerName());
			} else {
				message.setSendUser(con.getVisitor());
			}
			con.addMessage(message);
			con.setLastMessage(message.getContent());
			con.setMessageType(message.getType());
			con.setUpdateDate(message.getSendTime());
			if (!message.getRead()) {
				con.setUnreadMessages(con.getUnreadMessages() + 1);
			}
			pubQueue.remove(con);
			pubQueue.add(0, con);
			noticeListener(QUEUE_REFRESH);
		} else {
			LoadPubConversationWithMessage(message);
		}
	}

	/**
	 * 根据信息加载我的会话
	 * 
	 * @param message
	 */
	private void LoadPubConversationWithMessage(final TapLinkerMessage message) {
		new Cmd016(message.getConversationId(), new IMListener() {

			@Override
			public void handleMessage(TapLinkerConversation conversation) {
				conversation.addMessage(message);
				if (!message.getRead()) {
					conversation.setUnreadMessages(conversation
							.getUnreadMessages() + 1);
				}
				addToPublicQueue(conversation);
			}
		}).execute();
	}

	/**
	 * 根据信息加载公共队列会话
	 * 
	 * @param message
	 */
	private void LoadPriConversationWithMessage(final TapLinkerMessage message) {
		new Cmd016(message.getConversationId(), new IMListener() {

			@Override
			public void handleMessage(TapLinkerConversation conversation) {
				conversation.addMessage(message);
				if (!message.getRead()) {
					conversation.setUnreadMessages(conversation
							.getUnreadMessages() + 1);
				}
				addToPrivateQueue(conversation);
				noticeListener(MENU_REFRESH);
				noticeListener(HOME_REFRESH);

			}
		}).execute();
	}

	/**
	 * 消息添加消息到公共队列
	 * 
	 * @param message
	 */
	public void addToPriMessage(final TapLinkerMessage message) {
		String content = message.getContent();
		TapLinkerConversation con = getConversation(
				message.getConversationId(), privQueue);
		if (con != null) {
			if (!message.getRead() && con.getUnreadMessages() == 0) {
				priNum++;
			}
			if (!TextUtils.isEmpty(con.getCustomerName())) {
				message.setSendUser(con.getCustomerName());
			} else {
				message.setSendUser(con.getVisitor());
			}
			con.addMessage(message);
			con.setLastMessage(content);
			con.setMessageType(message.getType());
			con.setUpdateDate(message.getSendTime());
			if (!message.getRead()) {
				con.setUnreadMessages(con.getUnreadMessages() + 1);
			}
			privQueue.remove(con);
			privQueue.add(0, con);
			noticeListener(MENU_REFRESH);
			noticeListener(HOME_REFRESH);
			noticeListener(QUEUE_REFRESH);
		} else {
			LoadPriConversationWithMessage(message);
		}

	}

	/**
	 * 获取会话
	 * 
	 * @param conversationId
	 */
	public void readConversation(final String conversationId) {
		TapLinkerConversation con = getConversation(conversationId, pubQueue);
		if (con == null) {
			con = getConversation(conversationId, privQueue);
		}
		if (con == null) {
			return;
		}
		con.readMessage();
		noticeListener(QUEUE_REFRESH);
	}

	/**
	 * 分页获取size条信息
	 * 
	 * @param pageIndex
	 * @param size
	 * @param conversation
	 */
	public void getConversationByPage(int pageIndex, int size,
			final TapLinkerConversation conversation) {
		if (conversation != null) {
			if (pageIndex < 1) {
				pageIndex = 0;
				size = 1;
			}
			new Cmd015(pageIndex, size, conversation).execute();
		}
	}

	/**
	 * 分页获取信息
	 * 
	 * @param pageIndex
	 * @param conversation
	 */
	public void getConversationByPage(int pageIndex,
			final TapLinkerConversation conversation) {
		if (conversation != null) {
			if (pageIndex < 1) {
				pageIndex = 0;
			}
			new Cmd015(pageIndex, conversation).execute();
		}
	}

	/**
	 * 获取公共队列会话
	 * 
	 * @param conversation
	 */
	public void getPrivateConversation(final TapLinkerConversation conversation) {
		if (conversation != null) {
			new Cmd007(conversation).execute();
		}
	}

	/**
	 * 结束会话
	 * 
	 * @param reason
	 * @param context
	 */
	public void finishChat(final String reason, Context context) {
		if (!TextUtils.isEmpty(reason)) {
			new Cmd012(conversation.getId(), reason, context).execute();
		}
	}

	/**
	 * 重新加载公共队列或我的会话
	 */
	public void reloadQueue(final String source) {
		if (isPublicQueue) {
			new Cmd003(source).execute();
		} else {
			new Cmd004(source).execute();
		}
	}

	/**
	 * 加载更多公共队列或我的会话
	 */
	public void loadMore(final String source) {
		if (isPublicQueue) {
			new Cmd003(source, true).execute();
		} else {
			new Cmd004(source, true).execute();
		}
	}

	/**
	 * 委派
	 * 
	 * @param conversationId
	 * @param reason
	 * @param toUserId
	 */
	public void switchCustomer(final String conversationId,
			final String reason, long toUserId) {
		if (!TextUtils.isEmpty(conversationId) && !TextUtils.isEmpty(reason)
				&& toUserId != 0) {
			new Cmd011(conversationId, reason, toUserId).execute();
		}
	}

	/**
	 * 转接
	 * 
	 * @param conversationId
	 * @param reason
	 * @param toUserId
	 */
	public void transferCustomer(final String conversationId,
			final String reason, long toUserId) {
		if (!TextUtils.isEmpty(conversationId) && !TextUtils.isEmpty(reason)
				&& toUserId != 0) {
			new Cmd010(conversationId, reason, toUserId).execute();
		}
	}

	/**
	 * 获取会话
	 * 
	 * @param id
	 * @param queue
	 * @return
	 */
	public TapLinkerConversation getConversation(final String id,
			List<TapLinkerConversation> queue) {
		for (TapLinkerConversation con : queue) {
			if (con.getId().equals(id)) {
				return con;
			}
		}
		return null;
	}

	/**
	 * 获取会话
	 * 
	 * @param id
	 * @return
	 */
	public TapLinkerConversation getConversation(final String id) {
		TapLinkerConversation result = getConversation(id, pubQueue);
		if (result != null) {
			return result;
		}
		return getConversation(id, privQueue);
	}

	/**
	 * 添加用户列表
	 * 
	 * @param list
	 */
	public void addCustomerList(List<Cmd013Rep> list) {
		csList.clear();
		csList.addAll(list);
		noticeListener(USERLIST_REFRESH);
	}

	/**
	 * 获取用户列表
	 * 
	 * @param list
	 */
	public List<Cmd013Rep> getCsList() {
		new Cmd013().execute();
		return csList;
	}

	/**
	 * 相似联系人
	 * 
	 * @param ctx
	 * @param mobile
	 * @param email
	 */
	public void getMatchCustomer(Context ctx, String mobile, String email) {
		if (TextUtils.isEmpty(mobile) && TextUtils.isEmpty(email)) {
			return;
		}
	}

	@Override
	public void releaseResource() {
		pubQueue.clear();
		privQueue.clear();
		csList.clear();
	}

	@Override
	public void clear() {

	}
}
